#include <stdio.h>
#include <stdlib.h>
#include "dd_matrix.h"
#include "dd_string3d.h"
#include "dd_vector.h"
#include "dd_filetomesh.h"

void dd_string3d_init() {
	//Allocate memory
	letter = malloc(sizeof(struct dd_mesh*) *('z' -'a'));
	number = malloc(sizeof(struct dd_mesh*) *('9' -'0'));

	//Path of font (where `?` is the letter)
	char text[] = "obj/font/letter_?.obj";

	//For each letter
	unsigned char i;
	for (i = 'a'; i <= 'z'; i++)
	{
		//Change `?` in string with letter and load it
		text[16] = i;

		letter[i -'a'] = malloc(sizeof(struct dd_mesh));
		dd_filetomesh(letter[i -'a'], text, 0, 0, DD_OBJ);
	}

	//For each number
	for (i = '0'; i <= '9'; i++)
	{
		//Change `?` in string with number and load it
		text[16] = i;

		number[i -'0'] = malloc(sizeof(struct dd_mesh));
		dd_filetomesh(number[i -'0'], text, 0, 0, DD_OBJ);
	}
}

void dd_string3d_draw(struct dd_string3d *str3d, const char* text) {
	//New matrix
	dd_matrix_push();

	//Calculate length
	int length = -1;
	while (text[++length] != '\0');

	//Align (left is 0, so it's not needed)
	// 0.5f is the size of a letter
	float offset[16];
	switch (str3d->align)
	{
		//Center
		case 1:
			dd_matrix_identity(offset);
			dd_matrix_translates(offset, -(0.5f *length /2), 0.0f, 0.0f);
			dd_matrix_globalmult(offset);
			break;

		//Right
		case 2:
			dd_matrix_identity(offset);
			dd_matrix_translates(offset, -(0.5f *length), 0.0f, 0.0f);
			dd_matrix_globalmult(offset);
			break;
	}

	//For each letter in given text
	int i;
	for (i = 0; i < length; i++)
	{
		//Draw letter
		if (text[i] >= '0' && text[i] <= '9') {
			dd_mesh_draw(number[text[i] -'0']);
		} else
		if (text[i] >= 'a' && text[i] <= 'z') {
			dd_mesh_draw(letter[text[i] -'a']);
		}

		//Move one letter rightwards (for now I set them as 0.5 width each)
		float m[16];
		dd_matrix_identity(m);
		dd_matrix_translates(m, 0.5f, 0.0f, 0.0f);
		dd_matrix_globalmult(m);
	}

	//Remove local matrix
	dd_matrix_pop();
}

void dd_string3d_draw_int(struct dd_string3d *str3d, int num) {

	//At least 1 digit
	int length = 1;
	int diviner = 10;

	//Find extra digits
	while (num /diviner > 0)
	{
		//Add digit
		length++;

		//Next digit
		diviner *= 10;
	}

	//Move to last known digit
	diviner /= 10;

	//Create pointer array of length+1 (for \0)
	char *text = (char*) malloc( sizeof(char) *(length+1) );

	//For each digit
	int i;
	for (i = 0; i < length; i++)
	{
		//Convert digit to char
		text[i] = '0' +(num /diviner %10);

		//Previous digit
		diviner /= 10;
	}

	//Add terminating character
	text[length] = '\0';

	//Draw number
	dd_string3d_draw(str3d, text);

	free(text);
}
